package com.jnevision.overtime.controller;

import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Optional;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.api.ApiController;
import com.baomidou.mybatisplus.extension.api.R;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jnevision.common.CommonQuery;
import com.jnevision.overtime.model.Overtime;
import com.jnevision.overtime.model.OvertimeVO;
import com.jnevision.overtime.service.OvertimeServiceImpl;
import com.jnevision.overtimeapproval.model.OvertimeApprovalRecords;
import com.jnevision.overtimeapproval.service.OvertimeApprovalRecordsServiceImpl;
import com.jnevision.user.model.User;
import com.jnevision.user.service.UserServiceImpl;
import com.jnevision.util.JsonMapper;

/**
 * <p>
 * 加班申请 前端控制器
 * </p>
 *
 * @author gavin
 * @since 2019-07-14
 */

@RestController
@RequestMapping("/overtimes")
public class OvertimeController extends ApiController {
    @Autowired
    private OvertimeServiceImpl overtimeServiceImpl;
    @Autowired
    private OvertimeApprovalRecordsServiceImpl approvalRecordsServiceImpl;
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private UserServiceImpl userServiceImpl;

    /**
     * 提交加班
     * 
     * @param overtime
     * @param token
     * @return
     */
    @PostMapping
    @Transactional
    public R<Boolean> add(@RequestBody Overtime overtime, @RequestHeader(value = "token") String token) {
        User user = JsonMapper.nonDefaultMapper().fromJson(this.redisTemplate.boundValueOps(token).get(), User.class);
        if (user == null) {
            return this.failed("请登录后提交请假信息");
        }
        this.overtimeServiceImpl.save(overtime);

        OvertimeApprovalRecords oar = new OvertimeApprovalRecords();
        oar.setOvertimeId(overtime.getId());

        if (StringUtils.equals(user.getId(), overtime.getUserId())) {
            // 查找部门主管，TODO 让用户自己选择审批人，如果出现同一个部门两个相同角色的主管，系统无法判断;
            String parentUserId = this.userServiceImpl.getParentUser(user.getId()).getId();
            oar.setUserId(parentUserId);
            oar.setResult(overtime.getResult());
        } else {
            oar.setUserId(user.getId());
            oar.setResult(12); // 通过
            oar.setApprovalTime(LocalDateTime.now());
        }

        return this.success(this.approvalRecordsServiceImpl.save(oar));
    }

    /**
     * 更新结束时间和加班时长
     * 
     * @param overtime
     * @return
     */
    @GetMapping("/update/endtime")
    public R<Boolean> update(Overtime overtime) {
        OvertimeApprovalRecords record = this.approvalRecordsServiceImpl
            .getOne(new QueryWrapper<OvertimeApprovalRecords>().eq("overtime_id", overtime.getId()));
        record.setResult(overtime.getResult());
        this.approvalRecordsServiceImpl.updateById(record);

        return this.success(this.overtimeServiceImpl.updateById(overtime));
    }

    /**
     * 审批加班
     * 
     * @param oar
     * @return
     */
    @GetMapping
    public R<Boolean> update(OvertimeApprovalRecords oar) {
        oar.setApprovalTime(LocalDateTime.now());
        return this.success(this.approvalRecordsServiceImpl.updateById(oar));
    }

    @GetMapping("/list/{ids}")
    public R<Boolean> updateList(@PathVariable String[] ids) {

        Collection<OvertimeApprovalRecords> listByIds = this.approvalRecordsServiceImpl.listByIds(Arrays.asList(ids));
        listByIds.forEach(oar -> {
            oar.setReason("正常");
            oar.setResult(1);
            oar.setApprovalTime(LocalDateTime.now());
        });

        return this.success(this.approvalRecordsServiceImpl.updateBatchById(listByIds));
    }

    /**
     * 加班申请审批
     * 
     * @param token
     * @return
     */
    @GetMapping("/approve")
    public R<List<OvertimeVO>> getApprove(@RequestHeader(value = "token") String token) {
        User user = JsonMapper.nonDefaultMapper().fromJson(this.redisTemplate.boundValueOps(token).get(), User.class);
        return this.success(this.overtimeServiceImpl.getApprove(user.getId()));
    }

    /**
     * 加班申请详情
     * 
     * @param overtimeRecordId
     * @return
     */
    @GetMapping("/detail")
    public R<OvertimeVO> getApproveDetail(String overtimeRecordId) {
        return this.success(this.overtimeServiceImpl.getApproveDetail(overtimeRecordId));
    }

    /**
     * 加班申请列表
     * 
     * @return
     */
    @GetMapping("/page")
    public R<IPage<OvertimeVO>> page(Page<OvertimeVO> page, CommonQuery commonQuery, Integer result,
        @RequestHeader("token") String token) {
        String userId = this.userServiceImpl.getLoginUser(token).getId();
        commonQuery.setUserId(userId);
        return this.overtimeServiceImpl.page(page, commonQuery, result);
    }

    /**
     * 查询用户的剩余调休时间
     * 
     * @param userId
     * @return
     */
    @GetMapping("/resttime")
    public R<Float> getRestTime(String userId) {
        return this.success(Optional.ofNullable(this.overtimeServiceImpl.getRestTime(userId)).orElse(0f));
    }

    @GetMapping("/records")
    public R<IPage<OvertimeVO>> getRecordsByUser(Page<OvertimeVO> page, String userId) {

        return this.success(this.overtimeServiceImpl.getRecordsByUser(page, userId));
    }

}
